Android进阶5:SurfaceView实现原理分析 | 您所在的位置:网站首页 › surface go 3尺寸 › Android进阶5:SurfaceView实现原理分析 |
public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallback { //OtherCodes final ArrayList mCallbacks = new ArrayList();//重要的回调集合 final int[] mLocation = new int[2]; final ReentrantLock mSurfaceLock = new ReentrantLock(); // Current surface in use final Surface mSurface = new Surface(); //OtherCodes /** * Return the SurfaceHolder providing access and control over this * SurfaceView's underlying surface. * * @return SurfaceHolder The holder of the surface. */ //获取当前持有的holder public SurfaceHolder getHolder() { return mSurfaceHolder; } //surfaceView持有mSurfaceHolder的final类。对上面的surface进行管理 private final SurfaceHolder mSurfaceHolder = new SurfaceHolder() { private static final String LOG_TAG = "SurfaceHolder"; @Override public boolean isCreating() { return mIsCreating; } //把holder.callback添加到上面回调集合 @Override public void addCallback(Callback callback) { synchronized (mCallbacks) { // This is a linear search, but in practice we'll // have only a couple callbacks, so it doesn't matter. if (mCallbacks.contains(callback) == false) { mCallbacks.add(callback); } } } @Override public void removeCallback(Callback callback) { synchronized (mCallbacks) { mCallbacks.remove(callback); } } @Override public void setFixedSize(int width, int height) { if (mRequestedWidth != width || mRequestedHeight != height) { mRequestedWidth = width; mRequestedHeight = height; requestLayout(); } } @Override public void setSizeFromLayout() { if (mRequestedWidth != -1 || mRequestedHeight != -1) { mRequestedWidth = mRequestedHeight = -1; requestLayout(); } } @Override public void setFormat(int format) { // for backward compatibility reason, OPAQUE always // means 565 for SurfaceView if (format == PixelFormat.OPAQUE) format = PixelFormat.RGB_565; mRequestedFormat = format; if (mSurfaceControl != null) { updateSurface(); } } /** * @deprecated setType is now ignored. */ @Override @Deprecated public void setType(int type) { } @Override public void setKeepScreenOn(boolean screenOn) { runOnUiThread(() -> SurfaceView.this.setKeepScreenOn(screenOn)); } /** * Gets a {@link Canvas} for drawing into the SurfaceView's Surface * * After drawing into the provided {@link Canvas}, the caller must * invoke {@link #unlockCanvasAndPost} to post the new contents to the surface. * * The caller must redraw the entire surface. * @return A canvas for drawing into the surface. */ //封装的锁Canvas @Override public Canvas lockCanvas() { return internalLockCanvas(null, false); } /** * Gets a {@link Canvas} for drawing into the SurfaceView's Surface * * After drawing into the provided {@link Canvas}, the caller must * invoke {@link #unlockCanvasAndPost} to post the new contents to the surface. * * @param inOutDirty A rectangle that represents the dirty region that the caller wants * to redraw. This function may choose to expand the dirty rectangle if for example * the surface has been resized or if the previous contents of the surface were * not available. The caller must redraw the entire dirty region as represented * by the contents of the inOutDirty rectangle upon return from this function. * The caller may also pass null instead, in the case where the * entire surface should be redrawn. * @return A canvas for drawing into the surface. */ @Override public Canvas lockCanvas(Rect inOutDirty) { return internalLockCanvas(inOutDirty, false); } @Override public Canvas lockHardwareCanvas() { return internalLockCanvas(null, true); } //内部锁画布 private Canvas internalLockCanvas(Rect dirty, boolean hardware) { mSurfaceLock.lock(); if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " " + "Locking canvas... stopped=" + mDrawingStopped + ", surfaceControl=" + mSurfaceControl); Canvas c = null; if (!mDrawingStopped && mSurfaceControl != null) { try { //最终是锁住持有的surface的canvas,上面说的surface的lockcanvas是jni方法 if (hardware) { c = mSurface.lockHardwareCanvas(); } else { c = mSurface.lockCanvas(dirty); } } catch (Exception e) { Log.e(LOG_TAG, "Exception locking surface", e); } } if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " " + "Returned canvas: " + c); if (c != null) { mLastLockTime = SystemClock.uptimeMillis(); return c; } // If the Surface is not ready to be drawn, then return null, // but throttle calls to this function so it isn't called more // than every 100ms. long now = SystemClock.uptimeMillis(); long nextTime = mLastLockTime + 100; if (nextTime > now) { try { Thread.sleep(nextTime-now); } catch (InterruptedException e) { } now = SystemClock.uptimeMillis(); } mLastLockTime = now; mSurfaceLock.unlock(); return null; } /** * Posts the new contents of the {@link Canvas} to the surface and * releases the {@link Canvas}. * * @param canvas The canvas previously obtained from {@link #lockCanvas}. */ //封装的解锁canvas,实际也是调用Surafce的解锁canvas @Override public void unlockCanvasAndPost(Canvas canvas) { mSurface.unlockCanvasAndPost(canvas); mSurfaceLock.unlock(); } //获取当前持有的 surface @Override public Surface getSurface() { return mSurface; } @Override public Rect getSurfaceFrame() { return mSurfaceFrame; } }; } ...otherCodes复制代码 |
CopyRight 2018-2019 实验室设备网 版权所有 |